package com.jcake.vimlike.internal.commands;

import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextSelection;

import com.jcake.vimlike.RegisterManager;
import com.jcake.vimlike.internal.CommandParser;
import com.jcake.vimlike.internal.registers.Register;

public class PutCommand extends AbstractRegisterCountCommand {

	@Override
	protected String[] getFullCommands() {
		return new String[] { "p", "P", "gP", "gp" };
	}

	public void execute(String command) throws Exception {
		CommandParser parser = new CommandParser(command);
		Integer count = ((parser.getCount() != null) ? parser.getCount() : 1);
		Character register = parser.getRegister();
		String cmd = parser.getCommand();
		IDocument document = getDocument();
		ITextSelection selection = getSelection();

		if (register == null) {
			register = RegisterManager.UNNAMED_REGISTER;
		}

		Register registerToUse = RegisterManager.getInstance().getRegister(register);
		String registerContent = registerToUse.getContent();
		if ("".equals(registerContent)) {
			return;
		}

		int position = -1;
		int offset = selection.getOffset();
		boolean addNewLineAtBegining = false;
		if ("p".equals(cmd) || "gp".equals(cmd)) {
			if (registerToUse.getType() == Register.Type.LINE_ORIENTED) {
				IRegion currentLine = document.getLineInformationOfOffset(offset);
				String lineDelimiter = document.getLineDelimiter(document.getLineOfOffset(offset));
				position = currentLine.getOffset() + currentLine.getLength();
				if (lineDelimiter != null) {
					position += lineDelimiter.length();
				} else {
					addNewLineAtBegining = true;
				}
			} else {
				position = offset;
			}
		} else if ("P".equals(cmd) || "gP".equals(cmd)) {
			int line = document.getLineOfOffset(offset);
			if (line == 0) {
				position = document.getLineInformation(line).getOffset();
			} else {
				position = document.getLineInformation(line - 1).getOffset();
			}
		}

		StringBuilder contentToInsert = new StringBuilder();
		if (addNewLineAtBegining) {
			contentToInsert.append(document.getLegalLineDelimiters()[0]);
		}
		for (int i = 0; i < count; i++) {
			contentToInsert.append(registerContent);
		}
		document.replace(position, 0, contentToInsert.toString());

		if (cmd.startsWith("g")) {
			getTextEditor().selectAndReveal(position + contentToInsert.length(), 0);
		}
	}
}
